package com.tian.excel.filter;

import cn.hutool.json.JSONUtil;

import com.alibaba.excel.util.StringUtils;
import com.tian.excel.controller.OrderController;
import com.tian.excel.entity.User;
import com.tian.excel.mapper.UserMapper;
import com.tian.excel.utils.JWTUtil;
import com.tian.excel.vo.R;
import org.redisson.api.RBloomFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author: Tian
 * @version: 1.0
 * @since: 1.0
 * @date: 2024/7/30/18:56
 */
@Component
public class LoginFilter extends OncePerRequestFilter {

    private final UserMapper userMapper;

    private final RBloomFilter bloomFilter;



    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Autowired
    OrderController orderController;



    @Autowired
    public LoginFilter(RBloomFilter bloomFilter, UserMapper userMapper) {
        this.bloomFilter = bloomFilter;
        this.userMapper = userMapper;
        System.out.println("============登录过滤器的构造方法执行了============");
        List<User> users = userMapper.selectList(null);
        users.forEach(item->{

            System.out.println(item.getUsername());
            bloomFilter.add(item.getUsername());

        });
        System.out.println("============登录过滤器构造方法执行完了============");
    }
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        response.setContentType("application/json;charset=utf-8");
        String path = request.getRequestURI();
        String method = request.getMethod();
        String username1 = request.getParameter("username");
        System.out.println("==============");
        System.out.println(path);
        if("/login.html".equals(path)){
            filterChain.doFilter(request,response);
            return;
        }

        if("/order/notify".equals(path)){
            orderController.notify(request);
            return;
        }
        if("/login".equals(path)&&"POST".equals(method)){
            if(!bloomFilter.contains(username1)){
                System.out.println(bloomFilter.contains(username1));
                PrintWriter writer = response.getWriter();
                //返回一个账号不存在的json数据.
                R r=new R(500,"账号不存在",null);
                String jsonString = JSONUtil.toJsonStr(r);
                writer.write(jsonString);
                writer.flush();
                writer.close();
                return ;
            }
            //放行
            filterChain.doFilter(request,response);
            return;
        }

        //1. 从请求头中获取token令牌
        String token = request.getHeader("token");
        //2. 判断是否token为null
        if(StringUtils.isEmpty(token)){
            PrintWriter writer = response.getWriter();

            //3. 返回一个未登录的json数据.
            R r=new R(500,"未登录",null);
            String jsonString = JSONUtil.toJsonStr(r);
            writer.write(jsonString);
            writer.flush();
            writer.close();
            return;
        }

        //3. 验证token
        if(!JWTUtil.verify(token) || stringRedisTemplate.hasKey("token:"+username1)){
            PrintWriter writer = response.getWriter();

            //3. 返回一个未登录的json数据.
            R r=new R(500,"token失效",null);
            String jsonString = JSONUtil.toJsonStr(r);
            writer.write(jsonString);
            writer.flush();
            writer.close();
            return;
        }

        //把当前用户的信息封装到Authentication对象中
        SecurityContext context = SecurityContextHolder.getContext();
        //Object principal,账号
        // Object credentials,密码 null
        //			Collection<? extends GrantedAuthority> authorities:权限
        Map<String, Object> userinfo = JWTUtil.getInfo(token, "userInfo");
        String username = (String) userinfo.get("username");
        stringRedisTemplate.opsForValue().set("token:"+username,token,30, TimeUnit.MINUTES);
        System.out.println(stringRedisTemplate.getExpire("token:"+username, TimeUnit.MINUTES));

        List<String> permissions = (List<String>) userinfo.get("permissions");
        List<SimpleGrantedAuthority> collect = permissions.stream().map(item -> new SimpleGrantedAuthority(item)).collect(Collectors.toList());
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username,null,collect);
        context.setAuthentication(authenticationToken);



        //4. 放行
        filterChain.doFilter(request,response);


    }

}
